import numpy as np
from .base_optimizer import BaseOptimizer

class DE(BaseOptimizer):
    def __init__(self, dim, pop_size=50, max_iter=1000, F=0.5, CR=0.7):
        super().__init__(dim, pop_size, max_iter)
        self.F = F  # 差分权重
        self.CR = CR  # 交叉概率
        
    def optimize(self, objective_func, bounds=(-5, 5)):
        # 初始化种群
        population = self.initialize_population(bounds)
        fitness = np.array([objective_func(ind) for ind in population])
        
        # 记录最优解
        best_idx = np.argmin(fitness)
        self.best_solution = population[best_idx].copy()
        self.best_fitness = fitness[best_idx]
        
        for gen in range(self.max_iter):
            for i in range(self.pop_size):
                # 选择三个不同的个体
                idxs = [idx for idx in range(self.pop_size) if idx != i]
                a, b, c = population[np.random.choice(idxs, 3, replace=False)]
                
                # 变异
                mutant = a + self.F * (b - c)
                mutant = self.clip_to_bounds(mutant, bounds)
                
                # 交叉
                cross_points = np.random.random(self.dim) < self.CR
                if not np.any(cross_points):
                    cross_points[np.random.randint(0, self.dim)] = True
                    
                trial = np.where(cross_points, mutant, population[i])
                
                # 选择
                f = objective_func(trial)
                if f < fitness[i]:
                    fitness[i] = f
                    population[i] = trial
                    if f < self.best_fitness:
                        self.best_fitness = f
                        self.best_solution = trial.copy()
                        
        return self.best_solution, self.best_fitness 